package prototipo.server.logic.person;

import java.util.GregorianCalendar;
import java.util.List;

import prototipo.server.logic.exception.ExceptionLogic;
import prototipo.server.logic.transaction.Transaction;
import prototipo.server.logic.util.Address;
import prototipo.server.logic.util.Cnpj;
import prototipo.server.logic.util.Cpf;
import prototipo.server.logic.util.Email;
import prototipo.server.logic.util.Phone;

public abstract class Person implements PersonIF{
	private long id;
	private String name;
	private GregorianCalendar dateCreate;
	private Address address;
	private Phone phone;
	private Cnpj cnpj;
	private Cpf cpf;
	private Email email;
	private List<Transaction> historic;
	private String observation;

	/**
	 * @param name
	 * @param address
	 * @param phone
	 * @param cnpj
	 * @param cpf
	 * @param email
	 * @param observation
	 * @throws ExceptionLogic
	 */
	public Person(String name, Address address, Phone phone, Cnpj cnpj,
			Cpf cpf, Email email, String observation) throws ExceptionLogic {
		this.setName(name);
		this.setAddress(address);
		this.setPhone(phone);
		this.setCnpj(cnpj);
		this.setCpf(cpf);
		this.setEmail(email);
		this.setObservation(observation);
		GregorianCalendar dateCreate = new GregorianCalendar();
		this.setDateCreate(dateCreate);
	}

	/**
	 * @return the id
	 */
	public long getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 * @throws ExceptionLogic 
	 */
	public void setId(long id) throws ExceptionLogic {
		if (id < 0)
			throw new ExceptionLogic("Id negativo.",new Throwable("Id is negative."));
		this.id = id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 * @throws ExceptionLogic
	 */
	public void setName(String name) throws ExceptionLogic {
		if (name == null || name.equals(""))
			throw new ExceptionLogic("Nome vazio.", new Throwable(
					"String name is null."));
		this.name = name;
	}

	/**
	 * @return the dateCreate
	 */
	public GregorianCalendar getDateCreate() {
		return dateCreate;
	}

	/**
	 * @param dateCreate
	 *            the dateCreate to set
	 * @throws ExceptionLogic
	 */
	public void setDateCreate(GregorianCalendar dateCreate)
			throws ExceptionLogic {
		if (dateCreate == null)
			throw new ExceptionLogic("Data vazia.", new Throwable(
					"Date is null."));
		this.dateCreate = dateCreate;
	}

	/**
	 * @return the address
	 */
	public Address getAddress() {
		return address;
	}

	/**
	 * @param address
	 *            the address to set
	 * @throws ExceptionLogic
	 */
	public void setAddress(Address address) throws ExceptionLogic {
		if (address == null)
			throw new ExceptionLogic("Endereco vazio.", new Throwable(
					"Address is null."));
		this.address = address;
	}

	/**
	 * @return the phone
	 */
	public Phone getPhone() {
		return phone;
	}

	/**
	 * @param phone
	 *            the phones to set
	 * @throws ExceptionLogic
	 */
	public void setPhone(Phone phone) throws ExceptionLogic {
		this.phone = phone;
	}

	/**
	 * @return the cnpj
	 */
	public Cnpj getCnpj() {
		return cnpj;
	}

	/**
	 * @param cnpj
	 *            the cnpj to set
	 */
	public void setCnpj(Cnpj cnpj) {
		this.cnpj = cnpj;
	}

	/**
	 * @return the cpf
	 */
	public Cpf getCpf() {
		return cpf;
	}

	/**
	 * @param cpf
	 *            the cpf to set
	 */
	public void setCpf(Cpf cpf) {
		this.cpf = cpf;
	}

	/**
	 * @return the email
	 */
	public Email getEmail() {
		return email;
	}

	/**
	 * @param email
	 *            the email to set
	 * @throws ExceptionLogic
	 */
	public void setEmail(Email email) throws ExceptionLogic {
		this.email = email;
	}

	/**
	 * @return the observation
	 */
	public String getObservation() {
		return observation;
	}

	/**
	 * @param observation
	 *            the observation to set
	 */
	public void setObservation(String observation) {
		this.observation = observation;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public final int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cnpj == null) ? 0 : cnpj.hashCode());
		result = prime * result + ((cpf == null) ? 0 : cpf.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public final boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Person))
			return false;
		Person other = (Person) obj;
		if (cnpj == null) {
			if (other.cnpj != null)
				return false;
		} else if (!cnpj.equals(other.cnpj))
			return false;
		if (cpf == null) {
			if (other.cpf != null)
				return false;
		} else if (!cpf.equals(other.cpf))
			return false;
		return true;
	}

	public abstract void generateHistoric(short atLast);

}
